/**
 * @Project : algorithm-learning
 * @Author : Ruoyu Wang
 * @User : Momenta
 * @DateTime : 2024/3/16 13:54
 */

//小红有一棵树，树上每条边都有一个权值，小红想知道树上有多少条路径的权值和为偶数。
//
//输入描述
//  第一行输入一个整数 n(1<= n <=10^5) 表节点个数
//  接下来 n-1 行，每行输入三个整数 u,v(1<= u,v <=n),w(1<= w <=10^9) 表示树上的边
//输出描述
//  输出一个整数表示答案。
//
//示例 1
//输入
//3
//1 2 2
//2 3 2
//输出
//3
//说明
//  第1条: 1-2
//  第2条: 2-3
//  第3条: 1-2-3

//import java.util.Scanner;
//import java.util.List;
//import java.util.ArrayList;
//
//public class Main {
//    static class Edge {
//        int to, weight;
//
//        Edge(int to, int weight) {
//            this.to = to;
//            this.weight = weight;
//        }
//    }
//
//    private static List<List<Edge>> graph;
//    private static long eventCount = 0, oddCount = 0;
//
//    private static void dfs(int node, int parsent, int parity) {
//        if (parity == 0) {
//            eventCount++;
//        } else {
//            oddCount++;
//        }
//
//        for (Edge edge : graph.get(node)) {
//            if (edge.to != parsent) {
//                dfs(edge.to, node, (parity + edge.weight) % 2);
//            }
//        }
//    }
//
//    public static void main(String[] args) {
//        Scanner in = new Scanner(System.in);
//        int n = in.nextInt();
//
//        graph = new ArrayList<>();
//        for (int i = 0; i <= n; i++) {
//            graph.add(new ArrayList<>());
//        }
//
//        for (int i = 0; i < n - 1; i++) {
//            int u = in.nextInt();
//            int v = in.nextInt();
//            int w = in.nextInt();
//            graph.get(u).add(new Edge(v, w % 2));
//            graph.get(v).add(new Edge(u, w % 2));
//        }
//        dfs(1, -1, 0);
//        long result = eventCount * (eventCount - 1) / 2 + oddCount * (oddCount - 1) / 2;
//        System.out.println(result);
//    }
//}